/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package no.ffi.utils;

import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author stian
 */
public class FileAndPathTester {

    public enum Status { NONE, RO, WO, RW };
    
    public static class FileAndPathTestResult {
        public File file;
        public boolean exists;
        public boolean isDir;
        public boolean isFile;
        public boolean canRead;
        public boolean canWrite;
        public boolean canBeCreated;
        public boolean needsToBeCreated;
        public Status status;

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append("file=").append(file.toString()).append("\n");
            sb.append("exists=").append(exists).append("\n");
            sb.append("isDir=").append(isDir).append("\n");
            sb.append("isFile=").append(isFile).append("\n");
            sb.append("canRead=").append(canRead).append("\n");
            sb.append("canWrite=").append(canWrite).append("\n");
            sb.append("canBeCreated=").append(canBeCreated).append("\n");
            sb.append("needsToBeCreated=").append(needsToBeCreated).append("\n");
            sb.append("status=").append(status.toString());

            return sb.toString();
        }
        
        public FileAndPathTestResult(
                File file,
                boolean exists,
                boolean isDir,
                boolean isFile,
                boolean canRead,
                boolean canWrite,
                boolean canBeCreated,
                boolean needsToBeCreated) {
            this.file = file;
            this.exists = exists;
            this.isDir = isDir;
            this.isFile = isFile;
            this.canRead = canRead;
            this.canWrite = canWrite;
            this.canBeCreated = canBeCreated;
            this.needsToBeCreated = needsToBeCreated;
            
            if (needsToBeCreated && !canBeCreated) {
                status = Status.NONE;
            }
            else if (!canRead && !canWrite) {
                status = Status.NONE;
            }
            else if (canRead && !canWrite) {
                status = Status.RO;
            }
            else if (!canRead && canWrite) {
                status = Status.WO;
            }
            else {
                status = Status.RW;
            }
            System.out.println(this.toString());
        }
        
    }
    
    public static FileAndPathTestResult checkFile(String path, boolean create) {
        return check(new File(path), create, true);
    }

    public static FileAndPathTestResult checkFile(File file, boolean create) {
        return check(file, create, true);
    }

    public static FileAndPathTestResult checkDir(String path, boolean create) {
        return check(new File(path), create, false);
    }

    public static FileAndPathTestResult checkDir(File file, boolean create) {
        return check(file, create, false);
    }

    public static FileAndPathTestResult check(String path, boolean create, boolean checkAsFile) {
        return check(new File(path), create, checkAsFile);
    }

    public static FileAndPathTestResult check(File file, boolean create, boolean checkAsFile) {
        boolean configPathExists = file.exists();
        boolean configPathIsDir;
        boolean configPathIsFile;
        boolean configPathCanRead;
        boolean configPathCanWrite;
        boolean configPathCanBeCreated = false;
        boolean configPathNeedsToBeCreated = false;
        if (configPathExists) {
            configPathIsDir = file.isDirectory();
            configPathIsFile = file.isFile();
            configPathCanRead = file.canRead();
            configPathCanWrite = file.canWrite();
        } else {
            configPathNeedsToBeCreated = true;
            if (create) {
                configPathCanBeCreated = create(file, checkAsFile);
            } else {
                configPathCanBeCreated = file.getParentFile().canWrite();
            }
            configPathIsDir = file.isDirectory();
            configPathIsFile = file.isFile();
            configPathExists = file.exists();
            configPathCanRead = file.canRead();
            configPathCanWrite = file.canWrite();
        }
        return new FileAndPathTestResult(
                file,
                configPathExists, 
                configPathIsDir, 
                configPathIsFile,
                configPathCanRead, 
                configPathCanWrite, 
                configPathCanBeCreated, 
                configPathNeedsToBeCreated);
    }
    
    public static boolean createFile(String path) {
        return create(new File(path), true);
    }

    public static boolean createFile(File file) {
        return create(file, true);
    }
    
    public static boolean createDir(String path) {
        return create(new File(path), false);
    }

    public static boolean createDir(File file) {
        return create(file, false);
    }
    
    public static boolean create(File file, boolean createFile) {
        if (file.exists()) return false;
        boolean ret;
        try {
            ret = createFile ? file.createNewFile() : file.mkdirs();
        } catch (IOException ex) {
            ret = file.exists();
        }
        if (ret) {
            /*
             * TODO:
             * It has to be a more efficient way to set permissions?
             */
            file.setExecutable(false, false);
            file.setReadable(false, false);
            file.setWritable(false, false);
            file.setExecutable(createFile ? false : true);
            file.setReadable(true);
            file.setWritable(true);
        }
        return ret;
    }
}
